﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Futaba.SBus
{
	/// <summary>
	/// Base interface for more specific interfaces which describe handlers for 
	/// the different packet-types of an S.BUS stream
	/// </summary>
	/// <typeparam name="TData">The concrete information being parsed</typeparam>
	public interface ISbusParser<TData> : INotifyPropertyChanged
	{
		/// <summary>
		/// The reader which reads from the actual stream
		/// </summary>
		Readers.ISbusStreamReader Reader { get; set; }

		/// <summary>
		/// Returns the amount of bytes which were not considered part of a valid package
		/// </summary>
		/// <seealso cref="Reset"/>
		int BytesSkipped { get; }
		/// <summary>
		/// Returns the amount of packets which were successfully received and processed
		/// </summary>
		/// <seealso cref="Reset"/>
		int PacketsReceived { get; }
		/// <summary>
		/// Returns the amount of packets which were not fully processed
		/// </summary>
		/// <seealso cref="Reset"/>
		int PacketErrors { get; }
		/// <summary>
		/// Set to True from <see cref="ISbusParsingService"/>, if the current operation is to be aborted
		/// </summary>
		bool CancellationPending { set; }

		/// <summary>
		/// Holds the data of the parser
		/// </summary>
		IList<TData> ItemsCollection { get; set; }

		/// <summary>
		/// Raised when an element in the <see cref="ItemsCollection"/> has changed
		/// </summary>
		event EventHandler<TData> ItemUpdated;
		/// <summary>
		/// Raised (once per data-packet) when at least one element in the <see cref="ItemsCollection"/> has changed
		/// </summary>
		event EventHandler ItemsUpdated;
		/// <summary>
		/// Raised when a valid S.BUS packet has been received and parsed
		/// (regardless wether any channel has changed)
		/// </summary>
		event EventHandler DataReceived;

		/// <summary>
		/// Detect, if this type of data is being supplied in the current stream
		/// </summary>
		/// <returns>True, if this instance can parse data from the current <see cref="Reader"/></returns>
		bool DetectData(byte[] data);
		/// <summary>
		/// Read and parse data from the stream
		/// </summary>
		/// <returns>True, if a valid packet was detected, else False</returns>
		bool ReadPacket();
		/// <summary>
		/// Reset the counters
		/// </summary>
		/// <seealso cref="BytesSkipped"/>
		/// <seealso cref="PacketsReceived"/>
		/// <seealso cref="PacketErrors"/>
		void Reset();
	}
}
